package cn.lblbc.ziptool

import android.content.Intent
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Bundle
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.widget.Toast
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.lifecycleScope
import cn.lblbc.ziptool.databinding.ActivityTextFileViewerBinding
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream
import java.io.BufferedInputStream
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.InputStream
import java.util.zip.ZipInputStream

class FileViewerActivity : AppCompatActivity() {
    private lateinit var binding: ActivityTextFileViewerBinding
    private var archiveUri: Uri? = null
    private var filePath: String? = null
    private var fileName: String = ""
    private var actualFileNameInArchive: String? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityTextFileViewerBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // 设置Toolbar
        setSupportActionBar(binding.toolbar)
        supportActionBar?.setDisplayHomeAsUpEnabled(true)
        supportActionBar?.title = getString(R.string.file_viewer_title)

        // 获取传递的数据
        archiveUri = intent.getParcelableExtra("archive_uri")
        filePath = intent.getStringExtra("file_path")
        fileName = intent.getStringExtra("file_name") ?: "未知文件"

        // 设置标题
        title = fileName

        // 加载文件内容
        archiveUri?.let { uri ->
            filePath?.let { path ->
                loadFileContent(uri, path)
            }
        }
    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        menuInflater.inflate(R.menu.text_viewer_menu, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        return when (item.itemId) {
            android.R.id.home -> {
                finish()
                true
            }

            R.id.action_share -> {
                shareFile()
                true
            }

            else -> super.onOptionsItemSelected(item)
        }
    }

    private fun loadFileContent(archiveUri: Uri, filePath: String) {
        lifecycleScope.launch(Dispatchers.IO) {
            try {
                if (isImageFile(fileName)) {
                    val imageData = getImageFileContent(archiveUri, filePath)
                    withContext(Dispatchers.Main) {
                        binding.fileContentTextView.visibility = android.view.View.GONE
                        binding.fileContentImageView.visibility = android.view.View.VISIBLE
                        binding.fileContentImageView.setImageBitmap(imageData)
                    }
                } else {
                    val content = getTextFileContent(archiveUri, filePath)
                    withContext(Dispatchers.Main) {
                        binding.fileContentTextView.visibility = android.view.View.VISIBLE
                        binding.fileContentImageView.visibility = android.view.View.GONE
                        binding.fileContentTextView.text = content
                    }
                }
            } catch (e: Exception) {
                withContext(Dispatchers.Main) {
                    Toast.makeText(this@FileViewerActivity, "读取文件出错: ${e.message}", Toast.LENGTH_SHORT).show()
                    Log.e("FileViewer", "Error reading file", e)
                }
            }
        }
    }

    private fun isImageFile(fileName: String): Boolean {
        val imageExtensions = setOf("jpg", "jpeg", "png", "gif", "bmp", "webp")
        val extension = fileName.substringAfterLast(".", "").lowercase()
        return extension in imageExtensions
    }

    private fun getTextFileContent(archiveUri: Uri, filePath: String): String {
        val archiveFileName = getFileName(archiveUri)
        val fileExtension = archiveFileName.substringAfterLast(".", "").lowercase()
        val isTarGz = fileExtension == "gz" && archiveFileName.endsWith(".tar.gz", ignoreCase = true)

        contentResolver.openInputStream(archiveUri)?.use { inputStream ->
            if (isTarGz) {
                // 处理tar.gz文件
                GzipCompressorInputStream(BufferedInputStream(inputStream)).use { gzipInputStream ->
                    TarArchiveInputStream(gzipInputStream).use { tarInputStream ->
                        var entry = tarInputStream.nextEntry
                        while (entry != null) {
                            var entryName = entry.name
                            // 处理以 ./ 或 .\ 开头的路径，与ArchiveUtils保持一致
                            if (entryName.startsWith("./") || entryName.startsWith(".\\")) {
                                entryName = entryName.substring(2)
                            }
                            
                            if (!entry.isDirectory && (entryName == filePath || entry.name == filePath)) {
                                // 记录实际的文件名
                                actualFileNameInArchive = entry.name.substringAfterLast("/")
                                return tarInputStream.bufferedReader().readText()
                            }
                            entry = tarInputStream.nextEntry
                        }
                    }
                }
            } else {
                // 处理zip文件（包括apk和xapk）
                ZipInputStream(BufferedInputStream(inputStream)).use { zipInputStream ->
                    var entry = zipInputStream.nextEntry
                    while (entry != null) {
                        if (!entry.isDirectory && entry.name == filePath) {
                            // 记录实际的文件名
                            actualFileNameInArchive = entry.name.substringAfterLast("/")
                            return zipInputStream.bufferedReader().readText()
                        }
                        entry = zipInputStream.nextEntry
                    }
                }
            }
        }
        throw Exception("文件未找到")
    }

    private fun getImageFileContent(archiveUri: Uri, filePath: String): Bitmap {
        val archiveFileName = getFileName(archiveUri)
        val fileExtension = archiveFileName.substringAfterLast(".", "").lowercase()
        val isTarGz = fileExtension == "gz" && archiveFileName.endsWith(".tar.gz", ignoreCase = true)

        contentResolver.openInputStream(archiveUri)?.use { inputStream ->
            if (isTarGz) {
                // 处理tar.gz文件
                GzipCompressorInputStream(BufferedInputStream(inputStream)).use { gzipInputStream ->
                    TarArchiveInputStream(gzipInputStream).use { tarInputStream ->
                        var entry = tarInputStream.nextEntry
                        while (entry != null) {
                            var entryName = entry.name
                            // 处理以 ./ 或 .\ 开头的路径，与ArchiveUtils保持一致
                            if (entryName.startsWith("./") || entryName.startsWith(".\\")) {
                                entryName = entryName.substring(2)
                            }
                            
                            if (!entry.isDirectory && (entryName == filePath || entry.name == filePath)) {
                                // 记录实际的文件名
                                actualFileNameInArchive = entry.name.substringAfterLast("/")
                                
                                val buffer = ByteArray(8192)
                                val outputStream = ByteArrayOutputStream()
                                var bytesRead: Int
                                while (tarInputStream.read(buffer).also { bytesRead = it } != -1) {
                                    outputStream.write(buffer, 0, bytesRead)
                                }
                                val imageBytes = outputStream.toByteArray()
                                return BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size)
                            }
                            entry = tarInputStream.nextEntry
                        }
                    }
                }
            } else {
                // 处理zip文件（包括apk和xapk）
                ZipInputStream(BufferedInputStream(inputStream)).use { zipInputStream ->
                    var entry = zipInputStream.nextEntry
                    while (entry != null) {
                        if (!entry.isDirectory && entry.name == filePath) {
                            // 记录实际的文件名
                            actualFileNameInArchive = entry.name.substringAfterLast("/")
                            
                            val buffer = ByteArray(8192)
                            val outputStream = ByteArrayOutputStream()
                            var bytesRead: Int
                            while (zipInputStream.read(buffer).also { bytesRead = it } != -1) {
                                outputStream.write(buffer, 0, bytesRead)
                            }
                            val imageBytes = outputStream.toByteArray()
                            return BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size)
                        }
                        entry = zipInputStream.nextEntry
                    }
                }
            }
        }
        throw Exception("文件未找到")
    }

    private fun getFileName(uri: Uri): String {
        var result: String? = null
        contentResolver.query(uri, null, null, null, null)?.use { cursor ->
            if (cursor.moveToFirst()) {
                val nameIndex = cursor.getColumnIndex("_display_name")
                if (nameIndex >= 0) {
                    result = cursor.getString(nameIndex)
                }
            }
        }
        return result ?: "unknown"
    }

    private fun getActualFileName(filePath: String): String {
        return filePath.substringAfterLast("/")
    }

    private fun shareFile() {
        lifecycleScope.launch(Dispatchers.IO) {
            try {
                // 使用压缩包中的实际文件名或者从路径中提取文件名
                val sharingFileName = actualFileNameInArchive ?: getActualFileName(filePath ?: fileName)
                
                // 先将文件从压缩包中提取到临时目录
                // 直接使用原始文件名创建临时文件
                val tempFile = File(cacheDir, sharingFileName)
                // 如果文件已存在，先删除
                if (tempFile.exists()) {
                    tempFile.delete()
                }
                
                archiveUri?.let { uri ->
                    filePath?.let { path ->
                        extractFileToTemp(uri, path, tempFile)
                    }
                }

                // 使用FileProvider创建可分享的URI
                val fileUri = androidx.core.content.FileProvider.getUriForFile(
                    this@FileViewerActivity,
                    "${packageName}.fileprovider",
                    tempFile
                )

                // 创建分享Intent
                val shareIntent = Intent(Intent.ACTION_SEND).apply {
                    type = getMimeType(sharingFileName)
                    putExtra(Intent.EXTRA_STREAM, fileUri)
                    putExtra(Intent.EXTRA_SUBJECT, "分享文件: $sharingFileName")
                    addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
                }
                // 指定分享的文件名
                shareIntent.putExtra(Intent.EXTRA_TITLE, sharingFileName)
                
                // 添加额外的文件名标识
                shareIntent.putExtra("android.intent.extra.ORIGINATING_URI", fileUri)
                shareIntent.putExtra("android.intent.extra.FILE_NAME", sharingFileName)
                
                // 添加权限以允许接收应用读取文件
                val resInfoList = packageManager.queryIntentActivities(shareIntent, android.content.pm.PackageManager.MATCH_DEFAULT_ONLY)
                for (resolveInfo in resInfoList) {
                    val packageName = resolveInfo.activityInfo.packageName
                    grantUriPermission(packageName, fileUri, Intent.FLAG_GRANT_READ_URI_PERMISSION)
                }

                withContext(Dispatchers.Main) {
                    startActivity(Intent.createChooser(shareIntent, "分享文件"))
                }
            } catch (e: Exception) {
                withContext(Dispatchers.Main) {
                    Toast.makeText(this@FileViewerActivity, "分享文件出错: ${e.message}", Toast.LENGTH_SHORT).show()
                }
            }
        }
    }

    private fun extractFileToTemp(archiveUri: Uri, filePath: String, tempFile: File) {
        val archiveFileName = getFileName(archiveUri)
        val fileExtension = archiveFileName.substringAfterLast(".", "").lowercase()
        val isTarGz = fileExtension == "gz" && archiveFileName.endsWith(".tar.gz", ignoreCase = true)

        contentResolver.openInputStream(archiveUri)?.use { inputStream ->
            if (isTarGz) {
                // 处理tar.gz文件
                GzipCompressorInputStream(BufferedInputStream(inputStream)).use { gzipInputStream ->
                    TarArchiveInputStream(gzipInputStream).use { tarInputStream ->
                        var entry = tarInputStream.nextEntry
                        while (entry != null) {
                            var entryName = entry.name
                            // 处理以 ./ 或 .\ 开头的路径，与ArchiveUtils保持一致
                            if (entryName.startsWith("./") || entryName.startsWith(".\\")) {
                                entryName = entryName.substring(2)
                            }
                            
                            if (!entry.isDirectory && (entryName == filePath || entry.name == filePath)) {
                                tempFile.outputStream().use { outputStream ->
                                    tarInputStream.copyTo(outputStream)
                                }
                                break
                            }
                            entry = tarInputStream.nextEntry
                        }
                    }
                }
            } else {
                // 处理zip文件（包括apk和xapk）
                ZipInputStream(BufferedInputStream(inputStream)).use { zipInputStream ->
                    var entry = zipInputStream.nextEntry
                    while (entry != null) {
                        if (!entry.isDirectory && entry.name == filePath) {
                            tempFile.outputStream().use { outputStream ->
                                zipInputStream.copyTo(outputStream)
                            }
                            break
                        }
                        entry = zipInputStream.nextEntry
                    }
                }
            }
        }
    }

    private fun getMimeType(fileName: String): String {
        val extension = fileName.substringAfterLast(".", "")
        return when (extension.lowercase()) {
            "txt" -> "text/plain"
            "log" -> "text/plain"
            "pdf" -> "application/pdf"
            "jpg", "jpeg" -> "image/jpeg"
            "png" -> "image/png"
            "gif" -> "image/gif"
            "bmp" -> "image/bmp"
            "webp" -> "image/webp"
            "mp3" -> "audio/mpeg"
            "mp4" -> "video/mp4"
            "ts" -> "application/typescript"
            "tsx" -> "application/typescript"
            "js" -> "application/javascript"
            "jsx" -> "application/javascript"
            "json" -> "application/json"
            "xml" -> "application/xml"
            "css" -> "text/css"
            "html", "htm" -> "text/html"
            else -> "*/*"
        }
    }
}